/**
 * Viewport
 */
var VIEWPORT = "Viewport";
var VIEWPORT_VERSION = "0.2";
var theViewport = null;

function Viewport(w, h, x, y, s) {
	this.w = w;
	this.h = h;
	this.x = x;
	this.y = y;
	this.s = s;
}

function storeViewport(viewport) {
	var data = {
		version : VIEWPORT_VERSION,
		x       : viewport.x,
		y       : viewport.y,
		s       : viewport.s,
	};
	LocalStorage.set(VIEWPORT, JSON.stringify(data));
}
function loadViewport(w, h) {
	var data = JSON.parse(LocalStorage.get(VIEWPORT));
	if (data.version != VIEWPORT_VERSION) {
		LocalStorage.del(VIEWPORT);
		throw "Viewport is wrong version!";
	}
	return new Viewport(w, h, data.x, data.y, data.s);
}
function getViewport() {

	if (!theViewport) {
		var w = $(window).width();
		var h = $(window).height();

		if (LocalStorage.has(VIEWPORT)) {
			theViewport = loadViewport(w, h);
		} else {
			theViewport = new Viewport(w, h, 0, 0, 1);
		}
	}
	return theViewport;
}
Viewport.prototype.store = function() {
	storeViewport(this);
}

Viewport.prototype.getWorld = function(s) {
	var w = {
		x: (s.x + this.x - this.w/2) / this.s,
		y: (s.y + this.y - this.h/2) / this.s,
	}
	return w;
};
Viewport.prototype.getScreen = function(w) {
	var s = {
		x: (w.x * this.s) - this.x + this.w/2,
		y: (w.y * this.s) - this.y + this.h/2,
	}
	return s;
};

Viewport.prototype.set = function(values) {
	if (values.w != undefined) this.w = values.w;
	if (values.h != undefined) this.h = values.h;
	if (values.x != undefined) this.x = values.x;
	if (values.y != undefined) this.y = values.y;
	if (values.s != undefined) this.s = values.s;

//	storeViewport(this);

	this.update(this);
	return this;
};

Viewport.prototype.add = function(delta) {
	if (delta.w != undefined) this.w += delta.w;
	if (delta.h != undefined) this.h += delta.h;
	if (delta.x != undefined) this.x += delta.x;
	if (delta.y != undefined) this.y += delta.y;
	if (delta.s != undefined) this.s += delta.s;

//	storeViewport(this);

	this.update(this);
	return this;
};

Viewport.prototype.isVisible = function(x, y) {
	return false;
}

Viewport.prototype.setUpdate = function(update) {
	this.update = update;
}

var TestViewport = {};
TestViewport.testGetScreen = function() {
	assertEqual(new Viewport( 0, 0,  0, 0, 1).getScreen({x:0}).x,   0, "TestGetScreen x 1");
	assertEqual(new Viewport( 0, 0,  0, 0, 1).getScreen({x:10}).x, 10, "TestGetScreen x 2");
	assertEqual(new Viewport(20, 0,  0, 0, 1).getScreen({x:0}).x,  10, "TestGetScreen x 3");
	assertEqual(new Viewport(20, 0,  0, 0, 1).getScreen({x:10}).x, 20, "TestGetScreen x 4");
	assertEqual(new Viewport( 0, 0, 10, 0, 1).getScreen({x:0}).x, -10, "TestGetScreen x 5");
	assertEqual(new Viewport( 0, 0, 10, 0, 1).getScreen({x:10}).x,  0, "TestGetScreen x 6");

	assertEqual(new Viewport(0,  0, 0,  0, 1).getScreen({y:0}).y,   0, "TestGetScreen y 1");
	assertEqual(new Viewport(0,  0, 0,  0, 1).getScreen({y:10}).y, 10, "TestGetScreen y 2");
	assertEqual(new Viewport(0, 20, 0,  0, 1).getScreen({y:0}).y,  10, "TestGetScreen y 3");
	assertEqual(new Viewport(0, 20, 0,  0, 1).getScreen({y:10}).y, 20, "TestGetScreen y 4");
	assertEqual(new Viewport(0,  0, 0, 10, 1).getScreen({y:0}).y, -10, "TestGetScreen y 5");
	assertEqual(new Viewport(0,  0, 0, 10, 1).getScreen({y:10}).y,  0, "TestGetScreen y 6");
}
TestViewport.testGetWorld = function() {
	assertEqual(new Viewport(0, 0, 0, 0, 1).getWorld({x:0}).x, 0, "1");

	assertEqual(new Viewport(0, 0, 0, 0, 1).getWorld({y:0}).y, 0, "1");
}

TestViewport.test = function() {
	try {
		this.testGetScreen();
		this.testGetWorld();
	} catch (e) {
		console.error(e);
	}
}
